package com.shop.cloud.pay.common.feign;

import com.alipay.easysdk.payment.common.models.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.alipay.easysdk.util.generic.models.AlipayOpenApiGenericResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingRequest;
import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingUnfreezeRequest;
import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingResult;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.shop.cloud.common.core.constant.SecurityConstants;
import com.shop.cloud.common.core.constant.ServiceNameConstants;
import com.shop.cloud.common.core.util.R;
import com.shop.cloud.pay.common.dto.AliBaseRequest;
import com.shop.cloud.pay.common.entity.PayConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

/**
 * @author
 */
@FeignClient(contextId = "feignPayService", value = ServiceNameConstants.PAY_ADMIN)
public interface FeignPayService {
	/**
	 * 收款配置查询
	 * @param type
	 * @return
	 */
	@GetMapping("/payconfig/inside/{type}")
	R<PayConfig> getPayConfigByType(@PathVariable("type") String type, @RequestHeader(SecurityConstants.FROM) String from);
	/**
	 * 调用统一下单接口，并组装生成支付所需参数对象（微信支付）
	 *
	 * @param request 统一下单请求参数
	 * @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
	 */
	@PostMapping("/wxpay/unifiedOrder")
	R unifiedOrderWx(@RequestBody WxPayUnifiedOrderRequest request, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 处理支付回调数据（微信支付）
	 * @param xmlData
	 * @return
	 */
	@PostMapping("/wxpay/notifyOrder")
	R<WxPayOrderNotifyResult> notifyOrderWx(@RequestBody String xmlData, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * <pre>
	 * 申请退款（微信支付）
	 * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
	 * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/refund
	 * </pre>
	 *
	 * @param request 请求对象
	 * @return 退款操作结果 wx pay refund result
	 * @throws WxPayException the wx pay exception
	 */
	@PostMapping("/wxpay/refundOrder")
	R<WxPayRefundResult> refundOrderWx(@RequestBody WxPayRefundRequest request, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 退款回调（微信支付）
	 * @param xmlData
	 * @param from
	 * @return
	 */
	@PostMapping("/wxpay/notifyRefunds")
	R<WxPayRefundNotifyResult> notifyRefundsWx(@RequestBody String xmlData, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * <pre>
	 * 查询订单（微信支付）
	 * （适合于需要自定义子商户号和子商户appid的情形）.
	 * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
	 * 该接口提供所有微信支付订单的查询，商户可以通过查询订单接口主动查询订单状态，完成下一步的业务逻辑。
	 * 需要调用查询接口的情况：
	 * ◆ 当商户后台、网络、服务器等出现异常，商户系统最终未接收到支付通知；
	 * ◆ 调用支付接口后，返回系统错误或未知交易状态情况；
	 * ◆ 调用被扫支付API，返回USERPAYING的状态；
	 * ◆ 调用关单或撤销接口API之前，需确认支付状态；
	 * 接口地址：https://api.mch.weixin.qq.com/pay/orderquery
	 * </pre>
	 *
	 * @param request 查询订单请求对象
	 * @return the wx pay order query result
	 * @throws WxPayException the wx pay exception
	 */
	@PostMapping("/wxpay/queryOrder")
	R<WxPayOrderQueryResult> queryOrderWx(@RequestBody WxPayOrderQueryRequest request, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * <pre>
	 * 单次分账请求按照传入的分账接收方账号和资金进行分账，同时会将订单剩余的待分账金额解冻给特约商户。故操作成功后，订单不能再进行分账，也不能进行分账完结。
	 * 接口频率：30QPS
	 * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_1&index=1
	 * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/profitsharing
	 * </pre>
	 *
	 * @param request .
	 * @return .
	 * @throws WxPayException the wx pay exception
	 */
	@PostMapping("/wxpay/profitsharing")
	R<ProfitSharingResult> profitSharingWx(@RequestBody ProfitSharingRequest request, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * <pre>
	 * 1、不需要进行分账的订单，可直接调用本接口将订单的金额全部解冻给特约商户
	 * 2、调用多次分账接口后，需要解冻剩余资金时，调用本接口将剩余的分账金额全部解冻给特约商户
	 * 3、已调用请求单次分账后，剩余待分账金额为零，不需要再调用此接口。
	 * 接口频率：30QPS
	 * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_5&index=6
	 * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish
	 * </pre>
	 *
	 * @param request .
	 * @return .
	 * @throws WxPayException the wx pay exception
	 */
	@PostMapping("/wxpay/profitsharingfinish")
	R<ProfitSharingResult> profitSharingFinishWx(@RequestBody ProfitSharingUnfreezeRequest request, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 调用统一下单接口（支付宝）
	 *
	 * @param aliBaseRequest 统一下单请求参数
	 * @return
	 */
	@PostMapping("/alipay/unifiedOrder")
	R unifiedOrderAli(@RequestBody AliBaseRequest aliBaseRequest, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 查询订单（支付宝）
	 * @param aliBaseRequest
	 * @param from
	 * @return
	 */
	@PostMapping("/alipay/queryOrder")
	R<AlipayTradeQueryResponse> queryOrderAli(@RequestBody AliBaseRequest aliBaseRequest, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 申请退款（支付宝）
	 * @param aliBaseRequest
	 * @param from
	 * @return
	 */
	@PostMapping("/alipay/refundOrder")
	R<AlipayTradeRefundResponse> refundOrderAli(@RequestBody AliBaseRequest aliBaseRequest, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 查询退款（支付宝）
	 * @param aliBaseRequest
	 * @param from
	 * @return
	 */
	@PostMapping("/alipay/queryRefundOrder")
	R<AlipayTradeFastpayRefundQueryResponse> queryRefundOrderAli(@RequestBody AliBaseRequest aliBaseRequest, @RequestHeader(SecurityConstants.FROM) String from);

	/**
	 * 请求分账
	 * @param aliBaseRequest
	 * @param from
	 * @return
	 */
	@PostMapping("/alipay/profitsharing")
	R<AlipayOpenApiGenericResponse> profitSharingAli(@RequestBody AliBaseRequest aliBaseRequest, @RequestHeader(SecurityConstants.FROM) String from);

}
